package com.example.onlinemonitoring.comCenter;

import java.io.IOException;
import java.net.SocketException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.zip.CRC32;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.example.onlinemonitoring.Util.CRC16;
import com.example.onlinemonitoring.Util.CommPortManager;
import com.example.onlinemonitoring.Util.HexUtil;
import com.example.onlinemonitoring.model.Appdevice;
import com.example.onlinemonitoring.model.Byqpdsensor;
import com.example.onlinemonitoring.model.Gispdhistory;
import com.example.onlinemonitoring.model.Gispdsensor;
import com.example.onlinemonitoring.model.Sf6history;
import com.example.onlinemonitoring.model.Sf6sensor;
import com.example.onlinemonitoring.model.DataFile.DataFileHeader;
import com.example.onlinemonitoring.serviceImpl.AppdeviceServiceImpl;
//import com.example.onlinemonitoring.model.DataFile.DataFileHeader.PRPDGraph;
//import com.example.onlinemonitoring.model.DataFile.DataFileHeader.PRPSGraph;
import com.example.onlinemonitoring.serviceImpl.GispdsensorServiceImpl;
import com.example.onlinemonitoring.serviceImpl.Sf6sensorServiceImpl;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Scope;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.MqttSecurityException;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;

/**
 * GIS局放
 */
@Service("gispdCom")
@Scope("prototype")
public class GispdCom extends CommPortManager {
    @Autowired
    private GispdsensorServiceImpl gispdserviceimpl;
    @Autowired
    private AppdeviceServiceImpl appdeviceserviceimpl;
    private String PointName = "新监测点";
    private int PointCount = 1;
    int iGispdSend = 0;
    int iXYGispdSend = 0;
    int ibackup = 0;

    public ArrayList<Integer> XDalarmLevelList = new ArrayList<>();

    public ArrayList<String> XDalarmMessageList = new ArrayList<>();
    @Autowired
    private Sf6sensorServiceImpl sf6serviceimpl;

    // mqtt相关
    MqttClient client;
    int MqttHaveSignal = 0;
    int MqttSignalPower = 0;
    int MqttAddr = 0;
    String TOPIC = "/8E02000213012345/subnode/59425008002d005c0000/data_ctrl/property";
    int qos = 1;
    MqttMessage mqttMessage;
    DataFileHeader dataFileHeader = new DataFileHeader();

    String recvmsg[] = new String[2];
    String DischargeTypeXD[] = { "无特征放电", "自由金属颗粒放电", "悬浮电位体放电", "沿面放电", "尖端放" };

    public void ClearCache() {
        for (int i = 0; i < recvmsg.length; i++) {
            recvmsg[i] = "";
        }
    }

    @Override
    public void receiveData(String str) {
        str = str.toUpperCase();
        setText(str);
        switch (ad.getBrand()) {
            case "MQTT":
                XY(str);
                break;
            case "自产":
                ZC(str);
                break;
            case "西电":
                if (str.substring(0, 2).equals("01")) {
                    XDJF(str);
                } else if (str.substring(0, 2).equals("02")) {
                    XDWS(str);
                }
                break;
            default:
                return;
        }
    }

    public void XDWS(String str) {
        if (str.substring(2, 4).equals("04")) {
            int index = 6;
            addrindex++;
            for (int i = 0; i < (str.length() - 10) / 20; i++) {
                reSend[i+1] = 0;   
                
              
                float pressure = 0, temperature = 0, relativeHumidity = 0, density = 0, pressure20 = 0,
                        waterVaporPartialPressure = 0, dewPoint = 0, PPMVolumeFraction = 0;
                temperature = parseHex4(str.substring(index, index + 4)) * 0.1f;
                dewPoint = parseHex4(str.substring(index + 4, index + 8)) * 0.1f;
                PPMVolumeFraction = parsePHex4(str.substring(index + 8, index + 12));
                pressure = parsePHex4(str.substring(index + 12, index + 16)) * 0.001f;
                density = parsePHex4(str.substring(index + 16, index + 20)) * 0.1f;
                index += 20;
                setText("解析日新SF6微水密度通信数据：站点号：1 监测点" + (i + 1));
                setText("压力：" + pressure + "MPa");
                setText("压力(20℃)：" + pressure20 + "MPa");
                setText("温度：" + temperature + "℃");
                setText("相对湿度：" + relativeHumidity + "%");
                setText("密度：" + density + "kg/m³");
                setText("常压露点(20℃)：" + waterVaporPartialPressure + "MPa");
                setText("带压露点：" + dewPoint + "℃");
                setText("微水体积分数：" + PPMVolumeFraction + "ppmV");

                Sf6sensor sf6 = new Sf6sensor();
                sf6.setStationid(ad.getStationid());
                sf6.setDevicegroup(ad.getDevicegroup());
                sf6.setDeviceaddr((i + 1));
                Sf6sensor record = sf6serviceimpl.getModel(sf6);

                if (record == null) {
                    setText("当前数据库无监测点：" + (i + 1) + " ！ 请先添加该监测点！");
                    return;
                }
                sf6.setLasttemperature(temperature);
                sf6.setLasthumidity(relativeHumidity);
                sf6.setLastpressure(pressure);
                sf6.setLastpressure20(pressure20);
                sf6.setLastdensity(density);
                sf6.setLastdaiya(waterVaporPartialPressure);
                sf6.setLastchangya(dewPoint);
                sf6.setLastppm(PPMVolumeFraction);
                sf6.setDeviceaddr((i + 1));
                sf6.setStationid(ad.getStationid());
                sf6.setLastdatatime(new Date());
                sf6.setLastcommunicationstatus(0);
                sf6.setLasthisdatatime(addHistory(record));
                if (sf6serviceimpl.Update(sf6, false) == 0) {
                    setText("更新实时数据失败，请检查数据库连接");
                }
            }
        } else if (str.substring(2, 4).equals("02")) {
            int index = 6;
            for (int i = 0; i < (str.length() - 10) / 4; i++) {
                Sf6sensor sf6 = new Sf6sensor();
                sf6.setStationid(ad.getStationid());
                sf6.setDevicegroup(ad.getDevicegroup());
                sf6.setDeviceaddr((i + 1));
                Sf6sensor record = sf6serviceimpl.getModel(sf6);

                if (record == null) {
                    setText("当前数据库无监测点：" + (i + 1) + " ！ 请先添加该监测点！");
                    return;
                }
                String alm = "";
                if (parsePHex4(str.substring(index, index + 4)) == 1) {
                    alm += "微水报警,";
                    sf6.setLastalarmlevel(2);
                    sf6.setLastalarmmessage(alm);
                } else {
                    sf6.setLastalarmlevel(0);
                    sf6.setLastalarmmessage("");
                }
                index += 4;
                Appdevice add = new Appdevice();
                add.setDevicegroup(ad.getDevicegroup());
                add.setStationid(ad.getStationid());
                add.setSimple("sf6");
                add = appdeviceserviceimpl.select(add).get(0);
                if (add == null) {
                    return;
                }
                if (alm.length() == 0) {
                    GetNormalAlarm("微水" + record.getDeviceaddr(), record.getDevicegroup(), record.getDeviceaddr(), 0,
                            record.getPointname(),
                            "", false, add);
                    setText("无报警");
                } else {
                    GetNormalAlarm("微水" + record.getDeviceaddr(), record.getDevicegroup(), record.getDeviceaddr(), 0,
                            record.getPointname(),
                            alm, true, add);
                    setText(alm);
                }
                sf6.setLastdatatime(new Date());
                sf6.setLastcommunicationstatus(0);
                sf6.setLasthisdatatime(addHistory(record));
                if (sf6serviceimpl.Update(sf6, false) == 0) {
                    setText("更新实时数据失败，请检查数据库连接");
                }
            }
        }
    }

    private Date addHistory(Sf6sensor sensor) {
        if (sensor != null) {
            if (sensor.getLasthisdatatime() == null) {
                add(sensor);
                return new Date();
            } else {
                long lasttime = 0;
                long nowtime = 0;
                try {
                    lasttime = HexUtil.todate(sensor.getLasthisdatatime()).getTime();
                    nowtime = HexUtil.todate(new Date()).getTime();
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                int timersp = 60000;
                if (sensor.getLastalarmlevel() != 0) {
                    timersp = ad.getHisalarmtimersp() * 1000;
                } else {
                    timersp = ad.getHistimersp() * 1000;
                }
                if (lasttime + timersp < nowtime) {
                    add(sensor);
                    return new Date();
                }
            }
        }
        return null;
    }

    private void add(Sf6sensor sensor) {
        Sf6history his = new Sf6history();
        his.setDeviceaddr(sensor.getDeviceaddr());
        his.setDevicegroup(sensor.getDevicegroup());
        his.setInuse(sensor.getInuse());
        his.setAlarmlevel(sensor.getLastalarmlevel());
        his.setAlarmmessage(sensor.getLastalarmmessage());
        his.setChangya(sensor.getLastchangya());
        his.setChangyaalarmstatus(sensor.getLastchangyaalarmstatus());
        his.setDaiya(sensor.getLastdaiya());
        his.setDatatime(sensor.getLastdatatime());
        his.setDensity(sensor.getLastdensity());
        his.setDensityalarmstatus(sensor.getLastdensityalarmstatus());
        his.setHumidity(sensor.getLasthumidity());
        his.setHumidityalarmstatus(sensor.getLasthumidityalarmstatus());
        his.setPpm(sensor.getLastppm());
        his.setPpmalarmstatus(sensor.getLastppmalarmstatus());
        his.setPressure(sensor.getLastpressure());
        his.setPressurealarmstatus(sensor.getLastpressurealarmstatus());
        his.setStandby(sensor.getLaststandby());
        his.setTemperature(sensor.getLasttemperature());
        his.setTemperaturealarmstatus(sensor.getLasttemperaturealarmstatus());
        his.setMemo(sensor.getMemo());
        his.setPointname(sensor.getPointname());
        his.setStationid(sensor.getStationid());
        his.setStyle(sensor.getStyle());
        sf6serviceimpl.Add(his);
    }

    public void XDJF(String str) {
        str = str.toUpperCase();
        setText(str);

        String addrstr = str.substring(0, 2);
        // Integer addrint = parseHex4(addrstr);
        String tip = str.substring(2, 4);
        // if (!"04".equals(tip) && !"02".equals(tip))
        // return;
        
        int xdlen = str.length();
        // if (xdlen == 34)
        // recvmsg[0] = str.substring(6, str.length() - 4);
        // if (xdlen == 14)
        // recvmsg[1] = str.substring(6, str.length() - 4);

        if ("04".equals(tip)) {
            String pdmsg = str.substring(6, str.length() - 4);
            // String pdvmsg = recvmsg[1];
            addrindex++;
            int pdindex = 0;
            for (int i = 0; i < ad.getAddrmax() - ad.getAddrmin() + 1; i++) {
                reSend[i+1] = 0;


                int Dcp;
                float Daver;
                float phase = 0;
                Long RST = (long) 0;
                int TOT = 0;
                int Discharge = parseHex4(pdmsg.substring(pdindex, pdindex + 4));
                String DT = DischargeTypeXD[Discharge];
                pdindex += 4;
                Dcp = parseHex4(pdmsg.substring(pdindex, pdindex + 4));
                pdindex += 4;
                Daver = parseHex4(pdmsg.substring(pdindex, pdindex + 4)) * 0.01f - 80;
                pdindex += 4;
                RST = (long) parseHex4(pdmsg.substring(pdindex, pdindex + 4));
                pdindex += 4;
                float DischargeAmount = parseHex4(pdmsg.substring(pdindex, pdindex + 4)) * 0.01f - 80;
                pdindex += 4;
                phase = parseHex4(pdmsg.substring(pdindex, pdindex + 4)) * 0.1f;
                pdindex += 4;

                // pdvindex = pdvindex+ 4;
                SensorDataXD(i + 1, Dcp, Daver, DischargeAmount, phase, DT, RST, TOT, 0);
           
               
            }
           
         
        } else if ("02".equals(tip)) {
            String pdvmsg = str.substring(6, str.length() - 4);
            int pdvindex = 0;
            //XDalarmLevelList.clear();
            //XDalarmMessageList.clear();
            for (int i = 0; i < ad.getAddrmax() - ad.getAddrmin() + 1; i++) {
                Integer XDalarmLevel = 0;
                String XDalarmMessage = "";// 报警消息
                // pdindex = pdindex+ 24;
                Gispdsensor gis = new Gispdsensor();
                gis.setStationid(ad.getStationid());
                gis.setDevicegroup(ad.getDevicegroup());
                gis.setDeviceaddr(i + 1);
                Gispdsensor record = gispdserviceimpl.getModel(gis);
                if (record == null) {
                    setText("当前数据库无监测点：" + (i + 1) + " ！ 请先添加该监测点！");
                    return;
                }
                XDalarmLevel = parseHex4(pdvmsg.substring(pdvindex, pdvindex + 4));
                pdvindex += 4;
                if (XDalarmLevel == 1)
                {
                    XDalarmMessage += "一级报警,";
                }
                    Boolean iswarn = XDalarmLevel == 1 ? true : false;
                    GetNormalWarn("局放西电一级报警",
                            record.getDeviceaddr(), 0,
                            record.getPointname(), XDalarmMessage, iswarn);

                

                if (XDalarmLevel > 1)
                {
                    XDalarmMessage += "二级报警,";
                } 
                    Boolean isalarm = XDalarmLevel > 1 ? true : false;
                    GetNormalAlarm("局放西电二级报警", record.getDevicegroup(),
                            record.getDeviceaddr(), 0,
                            record.getPointname(), XDalarmMessage, isalarm);

                

                //XDalarmLevelList.add(XDalarmLevel);
                //XDalarmMessageList.add(XDalarmMessage);
                // alarmMessage += GetAlarmMessage(alarmLevel, "放电量");
                // XDalarmLevel = Math.max(XDalarmLevel, XDalarmLevel);
                gis.setLastalarmlevel(XDalarmLevel);
                gis.setLastalarmmessage(XDalarmMessage);
                gis.setLastcommunicationstatus(0);
                gis.setLasthisdatatime(addHistory(record));
                if (gispdserviceimpl.Update(gis, false) == 0) {
                    setText("更新实时数据失败，请检查数据库连接");
                }
            }
        }
    }

    public void XY(String str) {
        str = str.toUpperCase();
        setText(str);
        if (str.length() != 66)
            return;
        String addrstr = str.substring(0, 2);
        Integer addrint = parseHex4(addrstr);

        char[] carr = HexUtil.hexString2Chars(str);

        // 信号
        int HaveSignal = carr[4] & 0x1;
        int SignalPower = carr[5] % 7 + 53;
        // 放电量
        float DischargeAmount = (carr[29] * 256 + carr[30]) / 65535f;
        Random ran = new Random();
        int phase = 0;
        if (DischargeAmount != 0)
            phase = (int) (ran.nextFloat() * 360);

        // 放电类型
        int Discharge = (1 + addrint) % 4;

        // 复位后放电次数
        Long RST = (long) 0;
        int TOT = 0;
        reSend[addrint] = 0;
        addrindex++;
        String DT = DischargeType[Discharge];

        DataFileHeader dataFileHeader = new DataFileHeader();
        String currentPath = System.getProperty("user.dir");
        String MqttfileAddr = "zjrxGISPD" + MqttAddr;
        if (ad.getBrand().equals("MQTT")) {

            MqttHaveSignal = HaveSignal;
            MqttSignalPower = SignalPower;
            MqttAddr = addrint;
            MqttfileAddr = "zjrxGISPD" + MqttAddr + "_";
            dataFileHeader.Deletefile(MqttfileAddr, currentPath + "//rixingisjf//");

            if (mqttMessage != null) {
                dataFileHeader = new DataFileHeader().setDataFile(ad, MqttAddr, mqttMessage);
                MqttSensor(MqttAddr, MqttHaveSignal, MqttSignalPower, 0, dataFileHeader);
            } else {
                dataFileHeader = new DataFileHeader().setDefaultDataFile(ad, MqttAddr);
                MqttSensor(MqttAddr, MqttHaveSignal, MqttSignalPower, 0, dataFileHeader);
            }

        }
    }

    public void ZC(String str) {
        try {
            str = str.toUpperCase();
            setText(str);
            if (str.length() != 66)
                return;
            String addrstr = str.substring(0, 2);
            Integer addrint = parseHex4(addrstr);

            char[] carr = HexUtil.hexString2Chars(str);

            // 信号
            int HaveSignal = carr[4] & 0x1;
            int SignalPower = carr[5] % 7 + 53;
            // 放电量
            float DischargeAmount = (carr[29] * 256 + carr[30]) / 65535f;
            Random ran = new Random();
            int phase = 0;
            if (DischargeAmount != 0)
                phase = (int) (ran.nextFloat() * 360);

            // 放电类型
            int Discharge = (1 + addrint) % 4;

            // 复位后放电次数
            Long RST = (long) 0;
            int TOT = 0;
            if (carr[1] == 05) {
                DischargeAmount = (carr[29] * 256 + carr[30]);
                // DischargeAmount = parseHex88(str.substring(startIndex, startIndex+=2))
                addrint = carr[2] * 1;
                Discharge = carr[8] * 1;
                RST = carr[6] * 256l + carr[7];
                phase = carr[4] * 256 + carr[3];
            } else {
                reSend[addrint] = 0;
                addrindex++;
            }
            String DT = DischargeType[Discharge];

            SensorData(addrint, HaveSignal, SignalPower, DischargeAmount, phase, DT, RST, TOT);
        } catch (Exception e) {
            setText(e.toString());
        }

    }

    void SensorDataXD(Integer addrint, int Dcp, float Daver, float DischargeAmount, float phase, String DT,
            Long RST, int TOT, int alarmLevel) {
        Gispdsensor gis = new Gispdsensor();
        gis.setStationid(ad.getStationid());
        gis.setDevicegroup(ad.getDevicegroup());
        gis.setDeviceaddr(addrint);
        Gispdsensor record = gispdserviceimpl.getModel(gis);
        if (record == null) {
            setText("当前数据库无监测点：" + addrint + " ！ 请先添加该监测点！");
            return;
        }
        DischargeAmount = DischargeAmount * nto(record.getPdkvalue()) + isnull(record.getPdmvalue());
        setText("GIS局放设备返回数据： 站点号：1 监测点" + addrint);
        setText("放电概率:" + Dcp + "%");
        setText("放电均值：" + Daver + "dbm");
        setText("放电峰值：" + DischargeAmount + "dbm");
        setText("相位：" + phase + "度");
        setText("放电量类型：" + DT);
        setText("复位后放电次数：" + RST + "次");
        // setText("总放电次数：" + TOT);
        // gis.setLasthavesignal(HaveSignal);
        // gis.setLastsignalpower(SignalPower);
        gis.setLastdcp(Dcp);
        gis.setLastdaver(Daver);
        gis.setLastdischargeamount(DischargeAmount);
        gis.setLastphase(phase);
        gis.setLastdischargetype(DT);
        gis.setLastrst(RST);

        gis.setLasttot(RST);
        gis.setLastdatatime(new Date());
        // gis.setLastalarmlevel(alarmLevel);
        // AddAndUpdate(record, gis);
        // gis.setLastalarmlevel(alarmLevel);
        // gis.setLastalarmmessage("");
        gis.setLastcommunicationstatus(0);
        gis.setLasthisdatatime(addHistory(record));
        if (gispdserviceimpl.Update(gis, false) == 0) {
            setText("更新实时数据失败，请检查数据库连接");
        }
    }

    void SensorData(Integer addrint, int HaveSignal, int SignalPower, float DischargeAmount, float phase, String DT,
            Long RST,
            int TOT) {
        Gispdsensor gis = new Gispdsensor();
        gis.setStationid(ad.getStationid());
        gis.setDevicegroup(ad.getDevicegroup());
        gis.setDeviceaddr(addrint);
        Gispdsensor record = gispdserviceimpl.getModel(gis);
        if (record == null) {
            setText("当前数据库无监测点：" + addrint + " ！ 请先添加该监测点！");
            return;
        }
        DischargeAmount = DischargeAmount * nto(record.getPdkvalue()) + isnull(record.getPdmvalue());
        setText("GIS局放设备返回数据： 站点号：1 监测点" + addrint);
        setText("信号：" + HaveSignal);
        setText("信号强度：" + SignalPower);
        setText("放电量：" + DischargeAmount + "pC");
        setText("相位：" + phase + "度");
        setText("放电量类型：" + DT);
        setText("复位后放电次数：" + RST);
        setText("总放电次数：" + TOT);
        gis.setLasthavesignal(HaveSignal);
        gis.setLastsignalpower(SignalPower);
        gis.setLastdischargeamount(DischargeAmount);
        gis.setLastphase(phase);
        gis.setLastdischargetype(DT);
        gis.setLastrst(RST);

        gis.setLasttot(RST);
        gis.setLastdatatime(new Date());
        AddAndUpdate(record, gis);
    }

    @Transactional
    private void AddAndUpdate(Gispdsensor record, Gispdsensor gispdsensor) {
        int alarmLevel = 0, alarm = 0;// 报警等级
        String alarmMessage = "";// 报警消息
        alarmLevel = GetAlarmStatus(isnull(gispdsensor.getLastdischargeamount()),
                isnull(record.getDischargeamountalarm()),
                isnull(record.getDischargeamountalarm()), isnull(record.getDischargeamountwarning()),
                isnull(record.getDischargeamountwarning()),
                isnull(record.getLastalarmlevel()), true, "放电量", record.getDevicegroup(), record.getDeviceaddr(),
                record.getPointname());
        // alarm = isnull(gispdsensor.getLastalarmlevel());

        // int XDalarmLevel =0;
        // String XDalarmMessage = "";
        // if( XDalarmLevelList.size()>0)
        // XDalarmLevel = XDalarmLevelList.get(gispdsensor.getDeviceaddr() - 1);
        // if( XDalarmMessageList.size()>0)
        // XDalarmMessage = XDalarmMessageList.get(gispdsensor.getDeviceaddr() - 1);
         alarmMessage += GetAlarmMessage(alarmLevel, "放电量");
        // alarmMessage += XDalarmMessage;

        // alarmLevel = Math.max(alarmLevel, XDalarmLevel);
        // XDalarmLevel = 0;
        gispdsensor.setLastalarmlevel(alarmLevel);
        gispdsensor.setLastalarmmessage(alarmMessage);
        gispdsensor.setLastcommunicationstatus(0);
        gispdsensor.setLasthisdatatime(addHistory(record));
        if (gispdserviceimpl.Update(gispdsensor, false) == 0) {
            setText("更新实时数据失败，请检查数据库连接");
        }
    }

    private Date addHistory(Gispdsensor sensor) {
        if (sensor != null) {
            if (sensor.getLasthisdatatime() == null) {
                add(sensor);
                return new Date();
            } else {
                long lasttime = 0;
                long nowtime = 0;
                try {
                    lasttime = HexUtil.todate(sensor.getLasthisdatatime()).getTime();
                    nowtime = HexUtil.todate(new Date()).getTime();
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                int timersp = 60000;
                if (sensor.getLastalarmlevel() != 0) {
                    timersp = ad.getHisalarmtimersp() * 1000;
                } else {
                    timersp = ad.getHistimersp() * 1000;
                }
                if (lasttime + timersp < nowtime) {
                    add(sensor);
                    return new Date();
                }
            }
        }
        return null;
    }

    private void add(Gispdsensor sensor) {
        Gispdhistory his = new Gispdhistory();
        his.setStationid(sensor.getStationid());
        his.setDevicegroup(sensor.getDevicegroup());
        his.setDeviceaddr(sensor.getDeviceaddr());
        his.setPointname(sensor.getPointname());
        his.setHavesignal(sensor.getLasthavesignal());
        his.setSignalpower(sensor.getLastsignalpower());
        his.setDischargeamount(sensor.getLastdischargeamount());
        his.setDischargetype(sensor.getLastdischargetype());
        his.setRst(sensor.getLastrst());
        his.setTot(sensor.getLasttot());
        his.setPhase(sensor.getLastphase());
        his.setDcp(sensor.getLastdcp());
        his.setDaver(sensor.getLastdaver());
        his.setDatatime(sensor.getLastdatatime());
        his.setAlarmlevel(sensor.getLastalarmlevel());
        his.setAlarmmessage(sensor.getLastalarmmessage());
        his.setMemo(sensor.getMemo());
        his.setInuse(sensor.getInuse());
        his.setStyle(sensor.getStyle());
        gispdserviceimpl.Add(his);

    }

    @Async("threadPool")
    public void startSendThread(Appdevice Appdevice) throws Exception {
        checkType = "crc16";
        issend.put(Thread.currentThread().getId(), true);
        String cstr = "";
        String cmdtype = "";
        String nametype = "";
        int timeoutsp = (int) Math.round(Appdevice.getTimeoutsp() * 1000);
        int timersp = (int) Math.round(Appdevice.getTimersp() * 1000);
        switch (ad.getBrand()) {
            case "MQTT":
                MqttInit(Appdevice);
                break;
            case "自产":
                ZCSendInit(Appdevice);
                break;
            case "西电":
                XDSendInit(Appdevice);
                break;
            default:
                return;
        }

    }

    void ZCSendInit(Appdevice Appdevice) throws Exception {
        String cstr = "";
        String cmdtype = "";
        String nametype = "";
        int timeoutsp = (int) Math.round(Appdevice.getTimeoutsp() * 1000);
        int timersp = (int) Math.round(Appdevice.getTimersp() * 1000);
        while (issend.get(Thread.currentThread().getId()) != null) {
            rlock.lock();
            if (isrun) {
                if (addrindex > Appdevice.getAddrmax() || addrindex < Appdevice.getAddrmin())
                    addrindex = Appdevice.getAddrmin();
                cstr = String.format(Appdevice.getCmd(), String.format("%02X", addrindex));
                cstr = cstr + CRC16.calcCrc16(cstr);
                Send(cstr);
                reSend[addrindex]++;
                if (reSend[addrindex] > 3) {
                    gispdserviceimpl.UpdateStatus(ad, addrindex, 1);
                    reSend[addrindex] = 0;
                    addrindex++;
                }
            } else if (rescode != 0) {
                setText(resmsg[rescode]);
            }

            rlock.unlock();
            Thread.sleep(timersp);
        }
    }

    void XDSendInit(Appdevice Appdevice) throws Exception {
        String cstr = "";
        String cmdtype = "";
        String nametype = "";
        int timeoutsp = (int) Math.round(Appdevice.getTimeoutsp() * 1000);
        int timersp = (int) Math.round(Appdevice.getTimersp() * 1000);
        String cmd[] = new String[4];
        int i = 0;
        while (issend.get(Thread.currentThread().getId()) != null) {
            rlock.lock();
            if (isrun) {

                if (addrindex > Appdevice.getAddrmax() || addrindex < Appdevice.getAddrmin())
                    addrindex = Appdevice.getAddrmin();
                currcmd = 0;
                cmd[0] = "01041000000c";
                cmd[1] = "010200000002";
                cmd[2] = "02041000000A";
                cmd[3] = "020200000002";
                // for (int i = 0; i < 4; i++) {
                if (i >= 4) {
                    i = 0;

                }

                currcmd = i;
                if (currcmd == 0) {
                    ClearCache();
                }

                cstr = cmd[currcmd];
                cstr = cstr + CRC16.calcCrc16(cstr);
                Send(cstr);
                reSend[addrindex]++;
                if (reSend[addrindex] > 6) {// 从机收不到就不更新
                    gispdserviceimpl.UpdateStatus(ad, addrindex, 1);
                    sf6serviceimpl.UpdateStatus(ad, addrindex, 1);
                    reSend[addrindex] = 0;
                    addrindex++;

                }
                Thread.sleep(timersp);
                // sendCondition.await(timeoutsp, TimeUnit.MILLISECONDS);
                // currcmd++;
                // }

                i++;
            } else if (rescode != 0) {
                setText(resmsg[rescode]);
            }
            rlock.unlock();
            // Thread.sleep(timersp);
        }
    }

    void MqttInit(Appdevice Appdevice) throws Exception {
        String cstr = "";

        PointCount = ad.getAddrmax();
        String HOST = "tcp://127.0.0.1:1883";
        String clientid = "subClientgisjf";
        String userName = "xyjf";
        String passWord = "xyjf321";
        // host为主机名，test为clientid即连接MQTT的客户端ID，一般以客户端唯一标识符表示，MemoryPersistence设置clientid的保存形式，默认为以内存保存
        try {
            client = new MqttClient(HOST, clientid, new MemoryPersistence());
            // MQTT的连接设置
            MqttConnectOptions options = new MqttConnectOptions();
            options.setAutomaticReconnect(ON);
            // 设置是否清空session,这里如果设置为false表示服务器会保留客户端的连接记录，这里设置为true表示每次连接到服务器都以新的身份连接
            options.setCleanSession(true);
            // 设置连接的用户名
            options.setUserName(userName);
            // 设置连接的密码
            options.setPassword(passWord.toCharArray());
            // 设置超时时间 单位为秒
            options.setConnectionTimeout(10);
            // 设置会话心跳时间 单位为秒 服务器会每隔1.5*20秒的时间向客户端发送个消息判断客户端是否在线，但这个方法并没有重连的机制
            options.setKeepAliveInterval(20);
            // 设置回调函数
            client.setCallback(new MqttCallback() {
                public void connectionLost(Throwable cause) {
                    setText("connectionLost");
                }

                public void messageArrived(String topic, MqttMessage message) throws Exception {
                    if (topic.contains("59425008002d005c0000") == false)
                        return;
                    iXYGispdSend++;
                    setText("数据已更新");
                    mqttMessage = message;
                    // DataFileHeader dataFileHeader = new DataFileHeader().setDataFile(ad,
                    // MqttAddr, message);
                    String currentPath = System.getProperty("user.dir");
                    if (ibackup > 120) {
                        dataFileHeader.DeleteAll(currentPath + "//rixingisjfbackup//");
                        ibackup = 0;
                    }
                    ibackup++;
                }

                public void deliveryComplete(IMqttDeliveryToken token) {
                    System.out.println("deliveryComplete---------" + token.isComplete());
                }
            });
            client.connect(options);
            System.out.println("connect..." + TOPIC);
            // 订阅消息
            client.subscribe(TOPIC, qos);
            System.out.println("订阅成功！");
        } catch (Exception e) {
            e.printStackTrace();
        }

        while (issend.get(Thread.currentThread().getId()) != null) {
            rlock.lock();
            if (isrun) {
                if (addrindex > Appdevice.getAddrmax() || addrindex < Appdevice.getAddrmin())
                    addrindex = Appdevice.getAddrmin();
                cstr = String.format(Appdevice.getCmd(), String.format("%02X", addrindex));
                cstr = cstr + CRC16.calcCrc16(cstr);
                Send(cstr);
                reSend[addrindex]++;
                if (reSend[addrindex] > 3) {// 从机收不到就不更新
                    gispdserviceimpl.UpdateStatus(ad, addrindex, 1);
                    reSend[addrindex] = 0;
                    addrindex++;
                }

            }
            if (ad.getBrand().equals("MQTT")) {
                iGispdSend++;
                if (iGispdSend > (600 * 1000 / timersp)) {// 主机收不到尝试重启服务
                    if (iXYGispdSend <= 2) {
                        setText("出错，服务重启中。。。\r\n");
                        Runtime.getRuntime().exec("sc restart ");
                        String currentPath = "D:\\GatewayService_V0.3.17_20231229\\GatewayService.exe restart";
                        Runtime.getRuntime().exec(currentPath);
                        iGispdSend = 0;
                        iXYGispdSend = 0;
                    } else {
                        iGispdSend = 0;
                        iXYGispdSend = 0;
                    }
                }
            }

            rlock.unlock();
            Thread.sleep(timersp);
        }
    }

    void MqttSensor(int addr, int haveSignal, int signalPower, int tOT, DataFileHeader dataFileHeader) {
        SensorData(addr, haveSignal, signalPower, dataFileHeader.getDischargeAmount(),
                (int) dataFileHeader.getDischargePhase(), dataFileHeader.getDT(),
                (long) dataFileHeader.getDischargecount(), tOT);

        String currentPath = System.getProperty("user.dir");
        dataFileHeader.generateprpdData(dataFileHeader, currentPath + "\\rixingisjf\\" + "zjrxGISPD" + addr
                + "_MONT_SPDC1_21_" + dataFileHeader.getAcqtime() + ".dat");
        dataFileHeader.generateprpsData(dataFileHeader, currentPath + "\\rixingisjf\\" + "zjrxGISPD" + addr
                + "_MONT_SPDC1_22_" + dataFileHeader.getAcqtime() + ".dat");
        dataFileHeader.generateprpdData(dataFileHeader, currentPath + "\\rixingisjfbackup\\" + "zjrxGISPD" + addr
                + "_MONT_SPDC1_21_" + dataFileHeader.getAcqtime() + ".dat");
        dataFileHeader.generateprpsData(dataFileHeader, currentPath + "\\rixingisjfbackup\\" + "zjrxGISPD" + addr
                + "_MONT_SPDC1_22_" + dataFileHeader.getAcqtime() + ".dat");
    }

    public static byte[] floatArrayToByteArray(float[] floatArray) {
        ByteBuffer buffer = ByteBuffer.allocate(floatArray.length * 4);
        buffer.order(ByteOrder.LITTLE_ENDIAN); // 设置字节顺序为小端序，根据需要进行修改

        for (float value : floatArray) {
            buffer.putFloat(value);
        }

        return buffer.array();
    }

    @Override
    public void myClose() {
        try {
            if (ad.getBrand().equals("MQTT")) {
                client.unsubscribe(TOPIC);
                client.disconnect();
                client.close();
            }
        } catch (MqttException e) {
            e.printStackTrace();
        }
    }
}
